package com.zdxlz.fcmp.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdxlz.fcmp.business.dto.IpsecVpnConfigDto;
import com.zdxlz.fcmp.business.dto.ict.DeviceInfoDto;
import com.zdxlz.fcmp.business.dto.ict.IctIpsecConfig;
import com.zdxlz.fcmp.business.dto.mqtt.IpsecConfig;
import com.zdxlz.fcmp.business.entity.DeviceInfoEntity;
import com.zdxlz.fcmp.business.entity.IpsecVpnConfigEntity;
import com.zdxlz.fcmp.business.entity.IpsecVpnTemplateConfigEntity;
import com.zdxlz.fcmp.business.mapper.IpsecVpnConfigMapper;
import com.zdxlz.fcmp.business.service.IDeviceInfoService;
import com.zdxlz.fcmp.business.service.IIpsecVpnConfigService;
import com.zdxlz.fcmp.business.service.IIpsecVpnTemplateConfigService;
import com.zdxlz.fcmp.business.service.ITaskService;
import com.zdxlz.fcmp.business.vo.IpsecDetailVo;
import com.zdxlz.fcmp.business.vo.IpsecStatusVo;
import com.zdxlz.fcmp.business.vo.IpsecVpnConfigVo;
import com.zdxlz.fcmp.common.core.constant.CommonConstants;
import com.zdxlz.fcmp.common.core.constant.enums.ResCode;
import com.zdxlz.fcmp.common.core.exception.BizException;
import com.zdxlz.fcmp.common.core.util.CompletableFutureUtil;
import com.zdxlz.fcmp.common.core.util.JsonUtil;
import com.zdxlz.fcmp.common.mqtt.adapter.Mqttv5Adapter;
import com.zdxlz.fcmp.common.mqtt.dto.IctMqttRequest;
import com.zdxlz.fcmp.common.mqtt.dto.IctMqttResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.zdxlz.fcmp.common.core.constant.MqttMsgConstants.*;
import static com.zdxlz.fcmp.common.core.constant.enums.ResCode.*;

/**
 * <p>
 * IPSec配置表 服务实现类
 * </p>
 *
 * @author: aman
 * @since 2025-02-08
 */
@Service
@AllArgsConstructor
@Slf4j
public class IpsecVpnConfigServiceImpl extends ServiceImpl<IpsecVpnConfigMapper, IpsecVpnConfigEntity> implements IIpsecVpnConfigService {

    private final IIpsecVpnTemplateConfigService ipsecVpnTemplateConfigService;
    private final IDeviceInfoService deviceInfoService;
    private final IpsecVpnConfigMapper ipsecVpnConfigMapper;
    private final ITaskService taskService;
    private final Mqttv5Adapter mqttv5Adapter;

    private static IctMqttRequest<IpsecConfig> buildIctMqttReqData(IpsecConfig config, String localProtectedSubnet, String remoteProtectedSubnet, String localIp, String remoteIp) {
        config.setLocalSubNetList(List.of(localProtectedSubnet));
        config.setRemoteSubNetList(List.of(remoteProtectedSubnet));

        String msgId = IdUtil.simpleUUID();
        config.setWanInterface(localIp);
        config.setRemoteIP(remoteIp);
        IctMqttRequest<IpsecConfig> reqData = new IctMqttRequest<>();
        reqData.setId(msgId);
        reqData.setProperties(config);
        reqData.setMethod(MQTT_QUANTUM_SET_IPSEC_CONFIG_METHOD);
        return reqData;
    }

    private static void preDeviceIpCheck(String deviceAWanIp, String deviceBWanIp, String deviceAProtectedSubnet, String deviceBProtectedSubnet) {
        if (StrUtil.isBlank(deviceAWanIp) || StrUtil.isBlank(deviceBWanIp)) {
            throw new BizException(ResCode.ERROR_DEVICE_NOT_WAN_IP.getCode(), ResCode.ERROR_DEVICE_OFFLINE.getReason());
        }
        if (StrUtil.isBlank(deviceAProtectedSubnet) || StrUtil.isBlank(deviceBProtectedSubnet)) {
            throw new BizException(ResCode.ERROR_DEVICE_NOT_PROTECTED_SUBNET.getCode(), ResCode.ERROR_DEVICE_NOT_PROTECTED_SUBNET.getReason());
        }
        if (deviceAProtectedSubnet.equals(deviceBProtectedSubnet)) {
            throw new BizException(ResCode.ERROR_DEVICE_PROTECTED_SUBNET_CONFLICT.getCode(), ResCode.ERROR_DEVICE_PROTECTED_SUBNET_CONFLICT.getReason());
        }
    }

    private static void isDeviceOnline(String mac) {
        // TODO 查询设备是否在线
        if (false) {
            throw new BizException(ResCode.ERROR_DEVICE_OFFLINE.getCode(), ResCode.ERROR_DEVICE_OFFLINE.getReason());
        }
    }

    private static IpsecConfig buildMqttIPSecConfig(IpsecVpnConfigEntity ipsecVpnConfig, IpsecVpnTemplateConfigEntity templateConfig) {
        IpsecConfig config = new IpsecConfig();
        config.setDpdRetry(templateConfig.getDpdDpdretry());
        config.setEnable(BooleanUtil.toInt(ipsecVpnConfig.getEnable()));
        config.setIndex(ipsecVpnConfig.getDeviceIndexA());
        config.setIpSecType(templateConfig.getIpsecType().getCode());
        config.setEncapsulationMode(templateConfig.getEncapsulationMode().getCode());
        config.setIkeAuthenticationMethod(templateConfig.getIkeVerifyMethod().getName());
        config.setIkeAuthenticationAlgorithm(templateConfig.getIkeVerifyAlgorithm().getName());
        config.setIkeEncryptionAlgorithm(templateConfig.getIkeEncryptAlgorithm().getName());
        config.setIkeDHGroup(templateConfig.getIkedhGroup().getName());
        config.setIkeIDType(String.valueOf(templateConfig.getIkeType()));
        config.setIpSecTransform(templateConfig.getIpsecTransform().getName());
        config.setEspEncryptionAlgorithm(templateConfig.getIpsecEncryptAlgorithm().getName());
        config.setEspAuthenticationAlgorithm(templateConfig.getIpsecAuthAlgorithm().getName());
        config.setIpSecPFS(templateConfig.getIpsecPfs().getName());
        config.setIkeSAPeriod(String.valueOf(templateConfig.getIkeSaperiod()));
        config.setIpSecSATimePeriod(86400);
        config.setIpSecSATrafficPeriod(3600);
        config.setAhAuthenticationAlgorithm(templateConfig.getAhAuthAlgorithm().getName());
        config.setDpdEnable(BooleanUtil.toInt(templateConfig.getDpdEnable()));
        config.setDpdThreshold(templateConfig.getDpdThreshold());
        return config;
    }

    private static IctIpsecConfig buildIctIpsecConfig(IpsecVpnConfigEntity vpnConfigEntity, IpsecVpnTemplateConfigEntity templateConfig) {
        IctIpsecConfig config = new IctIpsecConfig();
        config.setName(vpnConfigEntity.getName());
        config.setId(vpnConfigEntity.getId());
        config.setEnable(vpnConfigEntity.getEnable());
        if (templateConfig != null) {
            config.setDpdRetry(templateConfig.getDpdDpdretry());
            config.setIpSecType(templateConfig.getIpsecType().getCode());
            config.setEncapsulationMode(templateConfig.getEncapsulationMode().getCode());
            config.setIkeAuthenticationMethod(templateConfig.getIkeVerifyMethod().getName());
            config.setIkeAuthenticationAlgorithm(templateConfig.getIkeVerifyAlgorithm().getName());
            config.setIkeEncryptionAlgorithm(templateConfig.getIkeEncryptAlgorithm().getName());
            config.setIkeDHGroup(templateConfig.getIkedhGroup().getName());
            config.setIkeIDType(String.valueOf(templateConfig.getIkeType()));
            config.setIpSecTransform(templateConfig.getIpsecTransform().getName());
            config.setEspEncryptionAlgorithm(templateConfig.getIpsecEncryptAlgorithm().getName());
            config.setEspAuthenticationAlgorithm(templateConfig.getIpsecAuthAlgorithm().getName());
            config.setIpSecPFS(templateConfig.getIpsecPfs().getName());
            config.setIkeSAPeriod(String.valueOf(templateConfig.getIkeSaperiod()));
            config.setIpSecSATimePeriod(templateConfig.getIpsecSatimePeriod());
            config.setIpSecSATrafficPeriod(templateConfig.getIpsecSatrafficPeriod());
            config.setAhAuthenticationAlgorithm(templateConfig.getAhAuthAlgorithm().getName());
            config.setDpdEnable(BooleanUtil.toInt(templateConfig.getDpdEnable()));
            config.setDpdThreshold(templateConfig.getDpdThreshold());
        }
        return config;
    }

    /**
     * @description：分页查询Ipsec配置信息
     * @author：aman
     * @date：2025/2/14 11:42
     */
    @Override
    public IPage<IpsecVpnConfigVo> getList(Page<IpsecVpnConfigEntity> page, IpsecVpnConfigDto ipsecVpnConfigDto) {
        LambdaQueryWrapper<IpsecVpnConfigEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(ipsecVpnConfigDto)) {
            queryWrapper
                    .like(StrUtil.isNotBlank(ipsecVpnConfigDto.getName()), IpsecVpnConfigEntity::getName, ipsecVpnConfigDto.getName())
                    .eq(ObjectUtil.isNotEmpty(ipsecVpnConfigDto.getEnable()), IpsecVpnConfigEntity::getEnable, BooleanUtil.toBoolean(ipsecVpnConfigDto.getEnable()));
        }
        Page<IpsecVpnConfigEntity> ipsecVpnConfigPage = baseMapper.selectPage(page, queryWrapper);

        List<IpsecVpnConfigVo> ticketInfoVoList = ipsecVpnConfigPage.getRecords().stream().map(this::convertToIpsecVpnConfigVo).collect(Collectors.toList());
        IPage<IpsecVpnConfigVo> vpnConfigVoPage = new Page<>(ipsecVpnConfigPage.getCurrent(), ipsecVpnConfigPage.getSize(), ipsecVpnConfigPage.getTotal());
        vpnConfigVoPage.setRecords(ticketInfoVoList);
        return vpnConfigVoPage;
    }

    @Override
    public IpsecDetailVo getDetailById(Integer id) {
        IpsecVpnConfigEntity configEntity = baseMapper.selectById(id);

        String macA = configEntity.getDeviceMacA();
        String macB = configEntity.getDeviceMacB();

        List<DeviceInfoEntity> devices = deviceInfoService.getListByMacs(List.of(macA, macB));


        Integer deviceIndexA = configEntity.getDeviceIndexA();

        String deviceAMsgId = IdUtil.simpleUUID();
        IctMqttRequest<Map<String, List<Integer>>> deviceRequest = new IctMqttRequest<>();
        deviceRequest.setId(deviceAMsgId);
        deviceRequest.setProperties(Map.of(MQTT_PUBLISH_LIST_FIELD, List.of(deviceIndexA)));
        deviceRequest.setMethod(MQTT_QUANTUM_GET_IPSEC_STATUS_METHOD);


        CompletableFuture<IctMqttResponse<?>> future = mqttv5Adapter.applyConfigurationAsync(macA, deviceRequest);

        IctMqttResponse<?> result = CompletableFutureUtil.getResult(future, MQTT_REPLY_TIMEOUT, TimeUnit.SECONDS);
        if (result == null) {
            return null;
        }

        List<IpsecStatusVo> list = JsonUtil.getListFromMap((Map<String, Object>) result.getResult(), MQTT_REPLY_LIST_FIELD, IpsecStatusVo.class);
        Optional<IpsecStatusVo> optional = list.stream().filter(item -> deviceIndexA.equals(item.getIndex()))
                .findFirst();

        boolean present = optional.isPresent();
        IpsecDetailVo detailDto = new IpsecDetailVo();
        detailDto.setDeviceList(devices);
        detailDto.setTemplateName(configEntity.getTemplateName());
        if (present) {
            detailDto.setStatus(optional.get());
            return detailDto;
        }

        return detailDto;
    }

    /**
     * @description：通过设备MAC地址查询IPsec模板配置信息
     * @author：aman
     * @date：2025/2/14 11:42
     */
    @Override
    public IPage<IctIpsecConfig> ictGetList(Page<IpsecVpnConfigEntity> page, DeviceInfoDto deviceInfoDto) {
        // 通过mac 查询VPN配置表，返回mac，模板id
        LambdaQueryWrapper<IpsecVpnConfigEntity> queryVpnWrapper = new LambdaQueryWrapper<>();
        queryVpnWrapper
                .eq(StrUtil.isNotBlank(deviceInfoDto.getMac()), IpsecVpnConfigEntity::getDeviceMacA, deviceInfoDto.getMac())
                .or()
                .eq(StrUtil.isNotBlank(deviceInfoDto.getMac()), IpsecVpnConfigEntity::getDeviceMacB, deviceInfoDto.getMac());

        IPage<IpsecVpnConfigEntity> ipsecVpnConfigPage = ipsecVpnConfigMapper.selectPage(page, queryVpnWrapper);
        List<String> deviceMacList = new ArrayList<>();
        List<IpsecVpnConfigEntity> records = ipsecVpnConfigPage.getRecords();
        List<String> deviceMacAList = records.stream().map(IpsecVpnConfigEntity::getDeviceMacA).toList();
        List<String> deviceMacBList = records.stream().map(IpsecVpnConfigEntity::getDeviceMacB).toList();
        deviceMacList.addAll(deviceMacAList);
        deviceMacList.addAll(deviceMacBList);
        Map<String, DeviceInfoEntity> deviceMap;
        if (!deviceMacList.isEmpty()) {
            List<DeviceInfoEntity> deviceInfoEntityList = deviceInfoService.getListByMacs(deviceMacList);
            deviceMap = deviceInfoEntityList.stream().collect(Collectors.toMap(DeviceInfoEntity::getMac, Function.identity()));
        } else {
            deviceMap = new HashMap<>();
        }
        Map<Integer, IpsecVpnTemplateConfigEntity> templateConfigMap;
        // 通过模板id查询所有模板
        Set<Integer> templateIds = records.stream().map(IpsecVpnConfigEntity::getIpsecTemplateId).collect(Collectors.toSet());
        if (!templateIds.isEmpty()) {
            List<IpsecVpnTemplateConfigEntity> templateConfigList = ipsecVpnTemplateConfigService.listByIds(templateIds);
            templateConfigMap = templateConfigList.stream().collect(Collectors.toMap(IpsecVpnTemplateConfigEntity::getId, Function.identity()));
        } else {
            templateConfigMap = new HashMap<>();
        }

        List<IctIpsecConfig> ictIpsecConfigs = new ArrayList<>();
        records.forEach(vpnConfig -> ictIpsecConfigs.add(convertToIctIpsecConfig(templateConfigMap, vpnConfig, deviceMap)));
        IPage<IctIpsecConfig> ictIpsecConfigPage = new Page<>(ipsecVpnConfigPage.getCurrent(), ipsecVpnConfigPage.getSize(), ipsecVpnConfigPage.getTotal());
        ictIpsecConfigPage.setRecords(ictIpsecConfigs);
        return ictIpsecConfigPage;
    }

    /**
     * @description：创建Ipsec配置信息
     * @author：aman
     * @date：2025/2/14 11:41
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createIpsecVpnConfig(IpsecVpnConfigEntity ipsecVpnConfigEntity) {
        verifyVpnNameRepeat(ipsecVpnConfigEntity);

        String macA = ipsecVpnConfigEntity.getDeviceMacA();
        String macB = ipsecVpnConfigEntity.getDeviceMacB();
        IpsecVpnTemplateConfigEntity templateConfigServiceById = ipsecVpnTemplateConfigService.getById(ipsecVpnConfigEntity.getIpsecTemplateId());
        ipsecVpnConfigEntity.setTemplateName(templateConfigServiceById.getName());

        LambdaQueryWrapper<DeviceInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .in(DeviceInfoEntity::getMac, ipsecVpnConfigEntity.getDeviceMacA())
                .or()
                .in(DeviceInfoEntity::getMac, ipsecVpnConfigEntity.getDeviceMacB());
        List<DeviceInfoEntity> deviceInfoEntities = deviceInfoService.getBaseMapper().selectList(queryWrapper);
        deviceInfoEntities.forEach(deviceInfoEntity -> {
            if (deviceInfoEntity.getMac().equals(macA)) {
                int newIpsecIndexA = deviceInfoEntity.getIpsecIndex() + 1;
                deviceInfoEntity.setIpsecIndex(newIpsecIndexA);
                ipsecVpnConfigEntity.setDeviceIndexA(newIpsecIndexA);
            }
            if (deviceInfoEntity.getMac().equals(macB)) {
                int newIpsecIndexB = deviceInfoEntity.getIpsecIndex() + 1;
                deviceInfoEntity.setIpsecIndex(newIpsecIndexB);
                ipsecVpnConfigEntity.setDeviceIndexB(newIpsecIndexB);
            }
            deviceInfoService.updateById(deviceInfoEntity);
        });
        int insert = baseMapper.insert(ipsecVpnConfigEntity);
        if (insert >= 1) {
            Map<String, DeviceInfoEntity> deviceInfoMap = deviceInfoEntities.stream().collect(Collectors.toMap(DeviceInfoEntity::getMac, Function.identity()));
            return sendIpsecConfigToDevice(ipsecVpnConfigEntity, deviceInfoMap);
        }
        log.error("【IPSec配置】创建失败，数据库插入失败");
        return false;
    }

    /**
     * @description：通过IpSec配置ID更新IPSec配置信息
     * @author：aman
     * @date：2025/2/14 11:40
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateIpsecVpnConfig(IpsecVpnConfigEntity vpnConfig) {
        verifyVpnNameRepeat(vpnConfig);

        Map<String, Object> queryPara = Map.of("id", vpnConfig.getId(), "enable", Boolean.TRUE);
        List<IpsecVpnConfigEntity> vpnConfigEntityList = ipsecVpnConfigMapper.selectByMap(queryPara);
        if (CollectionUtil.isNotEmpty(vpnConfigEntityList)) {
            if (vpnConfigEntityList.get(0).getEnable().equals(vpnConfig.getEnable()))
                throw new BizException(VPN_ACTIVATE_USED_NO_UPDATE.getCode(), VPN_ACTIVATE_USED_NO_UPDATE.getReason());
        }
        baseMapper.updateById(vpnConfig);
        return true;
    }

    /**
     * @description：通过IpSec配置ID删除IPSec配置信息
     * @author：aman
     * @date：2025/2/14 11:40
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteIpsecVpnConfig(List<Integer> ids) {
        if (CollectionUtil.isEmpty(ids))
            throw new BizException(IPSEC_ID_NOT_NULL.getCode(), IPSEC_ID_NOT_NULL.getReason());
        removeIpsec(ids.get(0));
        return true;
    }

    public boolean sendIpsecConfigToDevice(IpsecVpnConfigEntity ipsecVpnConfig, Map<String, DeviceInfoEntity> deviceInfoMap) {
        Integer templateId = ipsecVpnConfig.getIpsecTemplateId();
        IpsecVpnTemplateConfigEntity templateConfig = ipsecVpnTemplateConfigService.getById(templateId);

        IpsecConfig ipsecConfigA = buildMqttIPSecConfig(ipsecVpnConfig, templateConfig);
        IpsecConfig ipsecConfigB = buildMqttIPSecConfig(ipsecVpnConfig, templateConfig);

        String deviceMacA = ipsecVpnConfig.getDeviceMacA();
        String deviceMacB = ipsecVpnConfig.getDeviceMacB();

        isDeviceOnline(deviceMacA);
        isDeviceOnline(deviceMacB);

        DeviceInfoEntity deviceA = deviceInfoMap.get(deviceMacA);
        DeviceInfoEntity deviceB = deviceInfoMap.get(deviceMacB);

        Boolean deviceANat = deviceA.getNatFlag();
        Boolean deviceBNat = deviceB.getNatFlag();

        Boolean deviceAAnonymousFlag = deviceA.getAnonymousFlag();
        Boolean deviceBAnonymousFlag = deviceB.getAnonymousFlag();

        String deviceAProtectedSubnet = deviceA.getProtectedSubnet();
        String deviceBProtectedSubnet = deviceB.getProtectedSubnet();
        String deviceAWanIp = deviceA.getWanIp();
        String deviceBWanIp = deviceB.getWanIp();
        preDeviceIpCheck(deviceAWanIp, deviceBWanIp, deviceAProtectedSubnet, deviceBProtectedSubnet);

        IctMqttRequest<IpsecConfig> deviceARequest = buildIctMqttReqData(ipsecConfigA, deviceAProtectedSubnet, deviceBProtectedSubnet, deviceANat ? deviceA.getNatWanIp() : deviceAWanIp, deviceAAnonymousFlag ? CommonConstants.ANY_ADDRESS : deviceBWanIp);
        IctMqttRequest<IpsecConfig> deviceBRequest = buildIctMqttReqData(ipsecConfigB, deviceBProtectedSubnet, deviceAProtectedSubnet, deviceBNat ? deviceB.getNatWanIp() : deviceBWanIp, deviceBAnonymousFlag ? CommonConstants.ANY_ADDRESS : deviceAWanIp);

        CompletableFuture<IctMqttResponse<?>> futureA = mqttv5Adapter.applyConfigurationAsync(deviceA.getMac(), deviceARequest);
        CompletableFuture<IctMqttResponse<?>> futureB = mqttv5Adapter.applyConfigurationAsync(deviceB.getMac(), deviceBRequest);

        /*
        List<IctMqttResponse<?>> results = CompletableFutureUtil.getResults(List.of(futureA, futureB), MQTT_REPLY_TIMEOUT, TimeUnit.SECONDS);

        if (results == null) {
            throw new BizException(ResCode.ERR_COMMON_UN_KNOW.getCode(), ResCode.ERR_COMMON_UN_KNOW.getReason());
        }

        // 成功的数据
        List<IctMqttResponse<?>> successfulList = results.stream()
                .filter(item -> MqttResCode.SUCESS.getCode() == item.getCode())
                .toList();

        if (successfulList.size() != results.size()) {
            List<IctMqttResponse<?>> failedList = results.stream()
                    .filter(item -> MqttResCode.SUCESS.getCode() != item.getCode())
                    .toList();
            log.error("【MQTT】下发指令IPSec配置失败，部分设备未成功，信息：{}", failedList);
            return false;
        }
        */
        return true;

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeIpsec(Integer id) {
        IpsecVpnConfigEntity vpnConfig = getById(id);

        Integer deviceIndexA = vpnConfig.getDeviceIndexA();
        Integer deviceIndexB = vpnConfig.getDeviceIndexB();

        String deviceAMac = vpnConfig.getDeviceMacA();
        String deviceBMac = vpnConfig.getDeviceMacB();

        //TODO 删除IPSec配置时，需要保证设备在线
        isDeviceOnline(deviceAMac);

        String deviceAMsgId = IdUtil.simpleUUID();
        String deviceBMsgId = IdUtil.simpleUUID();
        IctMqttRequest<Map<String, List<Integer>>> deviceARequest = new IctMqttRequest<>();
        deviceARequest.setId(deviceAMsgId);
        deviceARequest.setProperties(Map.of(MQTT_PUBLISH_LIST_FIELD, List.of(deviceIndexA)));
        deviceARequest.setMethod(MQTT_QUANTUM_DEL_IPSEC_CONFIG_METHOD);

        IctMqttRequest<Map<String, List<Integer>>> deviceBRequest = new IctMqttRequest<>();
        deviceBRequest.setId(deviceBMsgId);
        deviceBRequest.setProperties(Map.of(MQTT_PUBLISH_LIST_FIELD, List.of(deviceIndexB)));
        deviceBRequest.setMethod(MQTT_QUANTUM_DEL_IPSEC_CONFIG_METHOD);


        CompletableFuture<IctMqttResponse<?>> futureA = mqttv5Adapter.applyConfigurationAsync(deviceAMac, deviceARequest);
        CompletableFuture<IctMqttResponse<?>> futureB = mqttv5Adapter.applyConfigurationAsync(deviceBMac, deviceBRequest);

        /*
        List<IctMqttResponse<?>> results = CompletableFutureUtil.getResults(List.of(futureA, futureB), MQTT_REPLY_TIMEOUT, TimeUnit.SECONDS);

        if (results == null) {
            throw new BizException(ResCode.ERR_COMMON_UN_KNOW.getCode(), ResCode.ERR_COMMON_UN_KNOW.getReason());
        }
        // 成功的数据
        List<IctMqttResponse<?>> successfulList = results.stream()
                .filter(item -> MqttResCode.SUCESS.getCode() == item.getCode())
                .toList();

        if (successfulList.size() != results.size()) {
            List<IctMqttResponse<?>> failedList = results.stream()
                    .filter(item -> MqttResCode.SUCESS.getCode() != item.getCode())
                    .toList();
            log.error("【MQTT】下发指令删除IPSec配置失败，部分设备未成功，信息：{}", failedList);
            return false;
        }
        */
        return removeById(id);
    }

    /**
     * @description：校验Vpn名称是否重复
     * @author：aman
     * @date：2025/2/14 17:41
     */
    private void verifyVpnNameRepeat(IpsecVpnConfigEntity vpnConfig) {
        Map<String, Object> oneEntity = Map.of("name", vpnConfig.getName());
        List<IpsecVpnConfigEntity> ipsecVpnConfigEntities = baseMapper.selectByMap(oneEntity);
        List<IpsecVpnConfigEntity> configList = ipsecVpnConfigEntities.stream().filter(entity -> !entity.getId().equals(vpnConfig.getId())).toList();
        if (CollectionUtil.isNotEmpty(configList))
            throw new BizException(VPN_NAME_IS_DUPLICATED.getCode(), VPN_NAME_IS_DUPLICATED.getReason());
    }

    private IpsecVpnConfigVo convertToIpsecVpnConfigVo(IpsecVpnConfigEntity vpnConfig) {
        IpsecVpnConfigVo vpnConfigVo = new IpsecVpnConfigVo();
        BeanUtil.copyProperties(vpnConfig, vpnConfigVo);
        vpnConfigVo.setConnectionStatus(Boolean.TRUE);
        return vpnConfigVo;
    }

    private IctIpsecConfig convertToIctIpsecConfig(Map<Integer, IpsecVpnTemplateConfigEntity> templateConfigMap,
                                                   IpsecVpnConfigEntity vpnConfigEntity,
                                                   Map<String, DeviceInfoEntity> deviceMap
    ) {
        IctIpsecConfig ictIpsecConfig = buildIctIpsecConfig(vpnConfigEntity, templateConfigMap.get(vpnConfigEntity.getIpsecTemplateId()));
        List<DeviceInfoDto> deviceList = new ArrayList<>();
        if (!deviceMap.isEmpty()) {
            DeviceInfoEntity deviceInfoA = deviceMap.get(vpnConfigEntity.getDeviceMacA());
            DeviceInfoEntity deviceInfoB = deviceMap.get(vpnConfigEntity.getDeviceMacB());
            DeviceInfoDto deviceADto = new DeviceInfoDto();
            BeanUtil.copyProperties(deviceInfoA, deviceADto);
            DeviceInfoDto deviceBDto = new DeviceInfoDto();

            BeanUtil.copyProperties(deviceInfoB, deviceBDto);
            deviceList.add(deviceADto);
            deviceList.add(deviceBDto);
        }
        ictIpsecConfig.setDeviceList(deviceList);
        return ictIpsecConfig;
    }
}
